//线段数模板

#include <iostream>
#include <vector>
#include <queue>
using namespace std;

#define lc (p << 1)
#define rc (p << 1 | 1)

typedef long long LL;
int n, m;
const int N = 1e5 + 10;

struct
{
	int l, r;
	LL sum, add;
}tree[N << 2];

LL arr[N];

void lazy(int p, LL add)
{
	LL l = tree[p].l; LL r = tree[p].r;
	tree[p].sum += (LL)(r - l + 1) * add;
	tree[p].add += add;
}

void pushup(int p)
{
	tree[p].sum = tree[lc].sum + tree[rc].sum;
}

//下放懒信息
void pushdown(int p)
{
	LL& add = tree[p].add;
	if (add)
	{
		lazy(lc, add);
		lazy(rc, add);
		add = 0;
	}
}

void build(int p, int l, int r)
{
	tree[p] = { l,r,arr[l],0 };
	if (l == r) return;

	int mid = l + (r - l) / 2;
	//构建左右子树
	build(lc, l, mid); build(rc, mid + 1, r);
	pushup(p);
}

void modify(int p, int x, int y, LL k)
{
	int l = tree[p].l; int r = tree[p].r;
	if (x <= l && y >= r)
	{
		lazy(p, k);
		return;
	}

	pushdown(p);
	int mid = l + (r - l) / 2;
	if (x <= mid) modify(lc, x, y, k);
	if (y > mid) modify(rc, x, y, k);
	pushup(p);
}


LL find(int p, int x, int y)
{
	int l = tree[p].l; int r = tree[p].r;
	if (x <= l && y >= r) return tree[p].sum;

	pushdown(p);
	int mid = l + (r - l) / 2;
	LL sum = 0;
	if (x <= mid) sum += find(lc, x, y);
	if (y > mid) sum += find(rc, x, y);
	return sum;
}

int main()
{
	cin >> n >> m;
	for (int i = 1; i <= n; i++)
	{
		cin >> arr[i];
	}
	build(1, 1, n);

	for (int i = 1; i <= m; i++)
	{
		int op, x, y;
		cin >> op >> x >> y;
		if (op == 1)
		{
			LL k; cin >> k;
			modify(1, x, y, k);
		}
		else
		{
			cout << find(1, x, y) << endl;
		}
	}
	return 0;
}